package com.newshub.business.service.impl;

import com.newshub.business.entity.Category;
import com.newshub.business.entity.News;
import com.newshub.business.entity.Source;
import com.newshub.business.dto.NewsQueryDTO;
import com.newshub.business.dto.PageResult;
import com.newshub.business.mapper.CategoryMapper;
import com.newshub.business.mapper.NewsMapper;
import com.newshub.business.mapper.SourceMapper;
import com.newshub.business.service.NewsService;
import com.newshub.logging.annotation.BusinessLog;
import com.newshub.logging.annotation.LogLevel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 新闻服务实现类
 */
@Service
public class NewsServiceImpl implements NewsService {
    
    @Autowired
    private NewsMapper newsMapper;
    
    @Autowired
    private CategoryMapper categoryMapper;
    
    @Autowired
    private SourceMapper sourceMapper;
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "获取所有分类")
    public List<Category> getCategories() {
        return categoryMapper.selectAllCategories();
    }
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "获取新闻源卡片数据")
    public List<Map<String, Object>> getSourceCards() {
        List<Source> sources = sourceMapper.selectAllSources();
        return sources.stream().map(source -> {
            Map<String, Object> card = new HashMap<>();
            card.put("id", source.getId());
            card.put("name", source.getName());
            card.put("homepage", source.getHomepage());
            card.put("regionName", source.getRegionName());
            
            // 统计该来源的新闻数量
            List<News> sourceNews = newsMapper.selectBySourceId(source.getId());
            card.put("newsCount", sourceNews.size());
            
            return card;
        }).collect(Collectors.toList());
    }
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "获取指定信源的新闻列表")
    public List<News> getNewsBySourceId(Integer sourceId, Integer categoryId, Integer limit) {
        List<News> newsList = newsMapper.selectBySourceId(sourceId);
        
        return newsList.stream()
            .filter(news -> categoryId == null || news.getCategoryId().equals(categoryId))
            .sorted((a, b) -> b.getPublishTime().compareTo(a.getPublishTime()))
            .limit(limit != null ? limit : 10)
            .collect(Collectors.toList());
    }
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "根据ID获取新闻详情")
    public News getNewsById(Integer newsId) {
        return newsMapper.selectById(newsId);
    }
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "获取首页新闻列表")
    public List<News> getHomeNews(Integer categoryId, Integer sourceId, Integer limit) {
        List<News> newsList;
        
        if (categoryId != null) {
            newsList = newsMapper.selectByCategoryId(categoryId);
        } else if (sourceId != null) {
            newsList = newsMapper.selectBySourceId(sourceId);
        } else {
            newsList = newsMapper.selectLatestNews(limit != null ? limit : 20);
        }
        
        return newsList.stream()
            .filter(news -> categoryId == null || news.getCategoryId().equals(categoryId))
            .filter(news -> sourceId == null || news.getSourceId().equals(sourceId))
            .sorted((a, b) -> b.getPublishTime().compareTo(a.getPublishTime()))
            .limit(limit != null ? limit : 20)
            .collect(Collectors.toList());
    }
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "搜索新闻")
    public List<News> searchNews(String keyword) {
        return newsMapper.searchByKeyword(keyword);
    }
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "分页搜索新闻")
    public PageResult<News> searchNewsPage(String keyword, Integer pageNum, Integer pageSize) {
        // 计算偏移量
        int offset = (pageNum - 1) * pageSize;
        
        // 查询总数
        Long total = newsMapper.countByKeyword(keyword);
        
        // 查询数据
        List<News> newsList = newsMapper.searchByKeywordPage(keyword, offset, pageSize);
        
        return PageResult.of(pageNum, pageSize, total, newsList);
    }
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "获取最新新闻")
    public List<News> getLatestNews(Integer limit) {
        return newsMapper.selectLatestNews(limit != null ? limit : 10);
    }
    
    // ==================== 管理功能实现 ====================
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "分页查询新闻列表")
    public PageResult<News> getNewsPage(NewsQueryDTO queryDTO) {
        // 计算偏移量
        int offset = (queryDTO.getPageNum() - 1) * queryDTO.getPageSize();
        
        // 查询总数
        Long total = newsMapper.countByQuery(queryDTO);
        
        // 查询数据
        List<News> newsList = newsMapper.selectByQuery(queryDTO, offset, queryDTO.getPageSize());
        
        return PageResult.of(queryDTO.getPageNum(), queryDTO.getPageSize(), total, newsList);
    }
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "添加新闻")
    public boolean addNews(News news) {
        // 设置创建时间和更新时间
        LocalDateTime now = LocalDateTime.now();
        news.setCreatedAt(now);
        news.setUpdatedAt(now);
        
        // 设置默认状态
        if (news.getStatus() == null) {
            news.setStatus(1);
        }
        
        // 设置默认浏览次数
        if (news.getViewCount() == null) {
            news.setViewCount(0);
        }
        
        // 设置默认热点状态
        if (news.getIsHot() == null) {
            news.setIsHot(0);
        }
        
        return newsMapper.insert(news) > 0;
    }
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "更新新闻")
    public boolean updateNews(News news) {
        // 设置更新时间
        news.setUpdatedAt(LocalDateTime.now());
        
        return newsMapper.update(news) > 0;
    }
    
    @Override
    @BusinessLog(level = LogLevel.WARN, description = "删除新闻")
    public boolean deleteNews(Integer id) {
        return newsMapper.deleteById(id) > 0;
    }
    
    @Override
    @BusinessLog(level = LogLevel.WARN, description = "批量删除新闻")
    public boolean batchDeleteNews(List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }
        return newsMapper.batchDeleteByIds(ids) > 0;
    }
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "更新新闻状态")
    public boolean updateNewsStatus(Integer id, Integer status) {
        return newsMapper.updateStatus(id, status) > 0;
    }
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "更新新闻热点状态")
    public boolean updateNewsHot(Integer id, Integer isHot) {
        return newsMapper.updateHot(id, isHot) > 0;
    }

    // ==================== 统计功能实现 ====================
    
    @Override
    @BusinessLog(level = LogLevel.INFO, description = "获取新闻趋势统计")
    public Map<String, Object> getNewsTrendStats(String period) {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> trendData = new ArrayList<>();
        
        try {
            switch (period.toLowerCase()) {
                case "day":
                    // 按天统计，默认统计最近7天
                    trendData = newsMapper.selectNewsCountByDay(7);
                    break;
                case "week":
                    // 按周统计，默认统计最近8周
                    trendData = newsMapper.selectNewsCountByWeek(8);
                    break;
                case "month":
                    // 按月统计，默认统计最近12个月
                    trendData = newsMapper.selectNewsCountByMonth(12);
                    break;
                default:
                    // 默认按天统计
                    trendData = newsMapper.selectNewsCountByDay(7);
                    break;
            }
            
            // 提取日期和数量数据
            List<String> dates = new ArrayList<>();
            List<Integer> counts = new ArrayList<>();
            
            for (Map<String, Object> item : trendData) {
                if ("day".equals(period)) {
                    dates.add(item.get("date").toString());
                } else if ("week".equals(period)) {
                    // 按周统计，使用yearWeek作为标签
                    String yearWeek = item.get("yearWeek").toString();
                    dates.add("W" + yearWeek.substring(4)); // 提取周数部分
                } else if ("month".equals(period)) {
                    dates.add(item.get("month").toString());
                }
                counts.add(Integer.valueOf(item.get("count").toString()));
            }
            
            result.put("dates", dates);
            result.put("counts", counts);
            result.put("total", counts.stream().mapToInt(Integer::intValue).sum());
            
        } catch (Exception e) {
            result.put("error", "获取新闻趋势数据失败: " + e.getMessage());
        }
        
        return result;
    }
}